#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <sys/epoll.h>
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <errno.h>


#include "io.h"


/*
 * 设置子进程中关闭父进程继承的fd
 * @param fd 父进程fd
 * @return 成功返回0，失败返回-1
 * @note 调用fcntl系统调用
*/
int fdcloexec(int fd){
    int old_flags=fcntl(fd,F_GETFD);
    if (old_flags==-1)
    {
        return -1;
    }
    int new_flags=old_flags|FD_CLOEXEC;
    if (fcntl(fd,F_SETFD,new_flags)==-1)
    {
        return -1;
    }
    return 0;
}


int fdnonblock(int fd){
    int old_flags=fcntl(fd,F_GETFL);
    if (old_flags==-1)
    {
        return -1;
    }
    int new_flags=old_flags|O_NONBLOCK;
    if (fcntl(fd,F_SETFL,new_flags)==-1)
    {
        return -1;
    }
    return 0;
}

//判断fd类型 1.dir 2.file 3.link 4.char 5.blk 6.fifo 7.sock
int fdtype(int fd){
    struct stat info;
    int ret=fstat(fd,&info);
    if (ret==-1)
    {
        return -1;
    }
    if (S_ISDIR(info.st_mode))
    {
        return 1;
    }else if (S_ISREG(info.st_mode))
    {
        return 2;
    }else if (S_ISLNK(info.st_mode))
    {
        return 3;
    }else if (S_ISCHR(info.st_mode))
    {
        return 4;
    }else if (S_ISBLK(info.st_mode))
    {
        return 5;
    }else if (S_ISFIFO(info.st_mode))
    {
        return 6;
    }else if (S_ISSOCK(info.st_mode))
    {
        return 7;
    }
    return 0; 
}

int move_fd(int destfd,...){
    va_list args;
    int srcfd;
    int ret=0;
    va_start(args,destfd);
    while ((srcfd=va_arg(args,int))!=-1)
    {
        if (srcfd==destfd)
        {
            continue;
        }
        if (dup2(srcfd,destfd)<0)
        {
            ret=-1;
            break;
        }
        close(srcfd);
    }
    va_end(args);
    return ret;
}


/*
 * 打开pidfd
 * @param pid 进程id
 * @param flags 打开标志
 * @return 成功返回pidfd，失败返回-1
 * @note 调用pidfd_open系统调用
 * @see pidfd_open
*/
int pidfd_open(pid_t pid,unsigned int flags){
    return syscall(SYS_pidfd_open, pid, flags);
}

/*
 * 获取pidfd对应的fd
 * @param pidfd pidfd
 * @param targetfd 目标fd
 * @param flags 打开标志
 * @return 成功返回fd，失败返回-1
 * @note 调用pidfd_getfd系统调用
*/
int pidfd_getfd(int pidfd,int targetfd,unsigned int flags){
    return syscall(SYS_pidfd_getfd,pidfd,targetfd,flags);
}


/*
 * 初始化epoll msg
 * @param fd 事件发生的fd
 * @param evts 事件类型
 * @param stream 事件发生的fd对应的文件流
 * @param extend 扩展参数
 * @return 成功返回epmsg，失败返回NULL
 * @note 调用calloc分配内存，并初始化
*/
void epollset(int epollfd,int action,epmsg_t *epmsg){
    struct epoll_event ev;
    ev.events = epmsg->events;
    ev.data.ptr=epmsg; 
    epoll_ctl(epollfd,action,epmsg->fd,&ev);
    if (action==EPOLL_CTL_DEL && epmsg != NULL)
    {
        free(epmsg);
    }
}

epmsg_t *epmsg_init(int fd,int evts,FILE* stream,void *extend){
    epmsg_t *epmsg=calloc(1,sizeof(epmsg_t));
    if (epmsg!=NULL)
    {       
        epmsg->events=evts;
        epmsg->extend=extend;
        epmsg->fd=fd;
        epmsg->stream=stream;
    }
    return epmsg;
}

//添加epoll msg
int epmsg_add(int epollfd,epmsg_t *epmsg){
    struct epoll_event ev;
    ev.events=epmsg->events;
    ev.data.ptr=epmsg;
    int ret=epoll_ctl(epollfd,EPOLL_CTL_ADD,epmsg->fd,&ev);
    return ret;
}

//删除epoll msg
int epmsg_del(int epollfd,epmsg_t *epmsg){
    int ret=epoll_ctl(epollfd,EPOLL_CTL_DEL,epmsg->fd,NULL);
    if (ret!=-1){
        if (epmsg->stream!=NULL)
        {
            fclose(epmsg->stream);
        }else{
            close(epmsg->fd);
        }
        free(epmsg);
    }
    return ret;
}

/*
 * 从文件流中按行读取数据
 * @param user 回调函数的用户参数
 * @param __in 输入文件流
 * @param __out 输出文件流
 * @param iosize 读取缓冲区大小
 * @param __worker 回调函数
 * @note 调用fgets系统调用，并调用回调函数处理每行数据  
*/
void freadlines(void *user,FILE *__in,FILE *__out,unsigned int iosize,io_work __worker){
    
    if (iosize<1024)
        iosize=1024;
    char buf[iosize];
    while (fgets(buf,iosize,__in))
    {   
        __worker(user,buf,__out);    
    }
}

// 定义行处理回调函数类型
typedef void (*LineCallback)(const char* line, void* context);

// 按行读取文件描述符的核心函数
int read_lines_from_fd(int fd, LineCallback callback, void* context) {
    // 将文件描述符转换为 FILE 流 (只读模式)
    FILE* stream = fdopen(fd, "r");
    if (!stream) {
        perror("fdopen failed");
        return -1;
    }

    char line[4096] = { 0 };    // 行缓冲区
    
    // 逐行读取直到文件结束
    while (fgets(line, 4095,stream) ) {
        // 调用用户提供的回调函数处理行
        callback(line, context);
    }

    // 检查是否因错误退出循环
    if (ferror(stream)) {
        perror("Error reading stream");
        fclose(stream);
        return -1;
    }
    
    // 关闭流 (注意：这也会关闭底层文件描述符)
    if (fclose(stream)) {
        perror("fclose failed");
        return -1;
    }
    
    return 0;
}


// ====================== 环形缓冲区模块 ======================

// 创建环形缓冲区
RingBuffer *ringbuffer_create(int size) {
    if (size <= 0) size = RINGBUFFER_DEFAULT_SIZE;
    RingBuffer *rb = malloc(sizeof(RingBuffer));
    if (!rb) return NULL;
    
    rb->buffer = malloc(size);
    if (!rb->buffer) {
        free(rb);
        return NULL;
    }
    
    rb->size = size;
    rb->read_pos = 0;
    rb->write_pos = 0;
    rb->count = 0;
    return rb;
}

// 销毁环形缓冲区
void ringbuffer_destroy(RingBuffer *rb) {
    if (rb) {
        free(rb->buffer);
        free(rb);
    }
}

// 重置环形缓冲区
void ringbuffer_reset(RingBuffer *rb) {
    if (rb) {
        rb->read_pos = 0;
        rb->write_pos = 0;
        rb->count = 0;
    }
}

// 获取可读数据量
int ringbuffer_readable_bytes(RingBuffer *rb) {
    return rb ? rb->count : 0;
}

// 获取可写空间大小
int ringbuffer_writable_bytes(RingBuffer *rb) {
    return rb ? (rb->size - rb->count) : 0;
}

// 查找分隔符位置（返回相对读位置的偏移量）
int ringbuffer_find_delimiter(RingBuffer *rb, char delim) {
    if (!rb || rb->count == 0) return -1;
    
    for (int i = 0; i < rb->count; i++) {
        int pos = (rb->read_pos + i) % rb->size;
        if (rb->buffer[pos] == delim) {
            return i;
        }
    }
    return -1;
}

// 从环形缓冲区读取数据
int ringbuffer_read(RingBuffer *rb, char *out, int len) {
    if (!rb || !out || len <= 0 || rb->count == 0) return 0;
    
    len = (len > rb->count) ? rb->count : len;
    int to_end = rb->size - rb->read_pos;
    
    if (len <= to_end) {
        memcpy(out, rb->buffer + rb->read_pos, len);
        rb->read_pos = (rb->read_pos + len) % rb->size;
    } else {
        memcpy(out, rb->buffer + rb->read_pos, to_end);
        memcpy(out + to_end, rb->buffer, len - to_end);
        rb->read_pos = len - to_end;
    }
    
    rb->count -= len;
    return len;
}

// 向环形缓冲区写入数据
int ringbuffer_write(RingBuffer *rb, const char *data, int len) {
    if (!rb || !data || len <= 0 || ringbuffer_writable_bytes(rb) == 0) return 0;
    
    len = (len > ringbuffer_writable_bytes(rb)) ? ringbuffer_writable_bytes(rb) : len;
    int to_end = rb->size - rb->write_pos;
    
    if (len <= to_end) {
        memcpy(rb->buffer + rb->write_pos, data, len);
        rb->write_pos += len;
    } else {
        memcpy(rb->buffer + rb->write_pos, data, to_end);
        memcpy(rb->buffer, data + to_end, len - to_end);
        rb->write_pos = len - to_end;
    }
    
    rb->count += len;
    return len;
}

// 从fd读取数据直到遇到分隔符（分隔符包含在结果中）
int read_until_delimiter(int fd, RingBuffer *rb, char *output, int max_len, char delim) {
    if (!rb || !output || max_len <= 0) return -1;
    
    while (1) {
        // 检查缓冲区中是否有分隔符
        int offset = ringbuffer_find_delimiter(rb, delim);
        if (offset >= 0) {
            int bytes_to_read = offset + 1; // 包含分隔符
            if (bytes_to_read > max_len) {
                // 输出缓冲区不足，返回错误
                return -2;
            }
            return ringbuffer_read(rb, output, bytes_to_read);
        }
        
        // 缓冲区已满但未找到分隔符
        if (ringbuffer_writable_bytes(rb) == 0) {
            // 读取部分数据避免阻塞
            int bytes_read = ringbuffer_read(rb, output, max_len);
            return (bytes_read > 0) ? bytes_read : -3;
        }
        
        // 从文件描述符读取数据
        char temp_buf[4096];
        int n = read(fd, temp_buf, sizeof(temp_buf));
        if (n < 0) {
            if (errno == EINTR) continue; // 被信号中断，重试
            if (errno == EAGAIN || errno == EWOULDBLOCK) return 0; // 非阻塞返回
            return -1; // 读取错误
        }
        if (n == 0) {
            // EOF，返回剩余数据
            return ringbuffer_read(rb, output, max_len);
        }
        
        // 写入环形缓冲区
        ringbuffer_write(rb, temp_buf, n);
    }
}

// // 测试环形缓冲区
// int main() {
//     // 创建一对socket用于测试
//     int sockfd[2];
//     if (socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK, 0, sockfd) == -1) {
//         perror("socketpair");
//         exit(EXIT_FAILURE);
//     }

//     // 创建环形缓冲区（默认大小1024）
//     RingBuffer *rb = ringbuffer_create(0);
//     if (!rb) exit(EXIT_FAILURE);
    

//     // 测试数据
//     const char *test_data[] = {
//         "HTTP/1.1 200 OK\r\n",
//         "Content-Type: text/plain\r\n",
//         "Content-Length: 31\r\n",
//         "\r\n",
//         "Hello, world!\n",
//         NULL
//     };

//     // 发送测试数据
//     for (int i = 0; test_data[i] != NULL; i++) {
//         write(sockfd[1], test_data[i], strlen(test_data[i]));
//         usleep(10000); // 模拟网络延迟
//     }

//     char output[4096];
//     int line_count = 0;
//     while (1) {
//         memset(output, 0, sizeof(output));
//         int n = read_until_delimiter(sockfd[0], rb, output, sizeof(output), '\n');
//         if (n > 0) {
//             // 处理读取到的一行数据（包含换行符）
//             printf("Line %d: %s", ++line_count, output);
//         } else if (n == 0) {
//             // 无数据（非阻塞模式）
//             break;
//             // usleep(100000); // 等待100ms
//         } else {
//             // 错误处理
//             break;
//         }
//     }
//     close(sockfd[0]);
//     close(sockfd[1]);
//     ringbuffer_destroy(rb);
//     return 0;
// }